﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<memory>
//模拟实现shared_ptr	
using namespace std;
struct Date
{
	int _year;
	int _month;
	int _day;

	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	~Date()
	{
	}
};
//namespace hbx
//{
//	template<class T>
//	class shared_ptr
//	{
//	public:
//		//构造
//		shared_ptr(T* ptr)
//			:_ptr(ptr)
//			,_pcount(new int(1))
//		{}
//		//析构
//		~shared_ptr()
//		{
//			if (--(*_pcount) == 0)
//			{
//				delete _ptr;
//				delete _pcount;
//			}
//		}
//		//拷贝构造
//		shared_ptr(const shared_ptr<T>& ps)
//			:_ptr(ps._ptr)
//			, _pcount(ps._pcount)
//		{
//			++(*_pcount);
//		}
//		//赋值重载
//		shared_ptr<T>& operator=(const shared_ptr<T>& ps)
//		{
//			if (--(*_pcount) == 0)
//			{
//				delete _ptr;
//				delete _pcount;
//			}
//
//			_ptr = ps._ptr;
//			_pcount = ps._pcount;
//			++(*_pcount);
//		}
//
//		T& operator*()
//		{
//			return *_ptr;
//		}
//
//		T* operator->()
//		{
//			return _ptr;
//		}
//	private:
//		T* _ptr;
//		int* _pcount;
//	};
//}

//int main()
//{
//	hbx::shared_ptr<Date> sp1(new Date(1,1,1));
//}

//int main()
//{
//	shared_ptr<Date> sp1(new Date(1, 1, 1));
//	shared_ptr<Date> sp2(sp1);
//	//use_count()：引用计数
//	cout << sp2.use_count() << endl;
//
//	shared_ptr<Date> sp3(new Date(2, 2, 2));
//	cout << sp3.use_count() << endl;
//}

//int main()
//{
//	auto_ptr<Date> p1(new Date(1,1,1));
//	auto_ptr<Date> p2(p1);
//
//	p1->_year++;
//	return 0;
//}


////模拟实现auto_ptr
//namespace hbx
//{
//	template<class T>
//	class auto_ptr
//	{
//	public:
//		//构造
//		auto_ptr(T* ptr)
//			:_ptr(ptr)
//		{}
//		//拷贝构造
//		auto_ptr(auto_ptr<T>& ap)
//			:_ptr(ap._ptr)
//		{
//			ap._ptr=nullptr;//指针置为空，管理权转换
//		}
//		//赋值重载
//		auto_ptr<T>& operator=(const auto_ptr<T>& ap)
//		{
//			if (this != &ap)
//			{
//				if (_ptr)
//				{
//					delete _ptr;//释放被赋值对象的资源，这个对象是已经存在的是new出来的资源。所以deletes
//				}
//				_ptr = ap._ptr;
//				ap._ptr = nullptr;//赋完值把赋值对象的指针置为空
//			}
//			return *this;
//		}
//
//		~auto_ptr()
//		{
//			if (_ptr)
//			{
//				delete _ptr;
//			}
//		}
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		T* operator->()
//		{
//			return _ptr;
//		}
//	private:
//		T* _ptr;
//	};
//
//}
//
//int main()
//{
//	hbx::auto_ptr<Date> a1(new Date(1, 1, 1));
//	hbx::auto_ptr<Date> a2(a1);
//	return 0;
//}

//int main()
//{
//	unique_ptr<Date> u1(new Date(1, 1, 1));
//	unique_ptr<Date> u2(move(u1));
//	return 0;
//
//}

//unique_ptr简单模拟实现
//namespace hbx
//{
//	template<class T>
//	class unique_ptr
//	{
//	public:
//		//构造
//		unique_ptr(T* ptr)
//			:_ptr(ptr)
//		{}
//		//析构
//		~unique_ptr()
//		{
//			if (_ptr)
//			{
//				delete _ptr;
//			}
//		}
//		//拷贝构造
//		unique_ptr(const unique_ptr<T>& up) = delete;
//		//复制重载
//		unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;
//		//移动构造
//		unique_ptr(unique_ptr<T>&& up)
//			:_ptr(up._ptr)
//		{
//			up._ptr = nullptr;
//		}
//		//移动赋值
//		unique_ptr<T>& operator=(unique_ptr<T>&& up)
//		{
//			if (_ptr)
//			{
//				delete _ptr;
//			}
//			_ptr = up.ptr;
//			up.ptr = nullptr;
//		}
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		T* operator->()
//		{
//			return _ptr;
//		}
//	private:
//		T* _ptr;
//	};
//}
//
//int main()
//{
//	hbx::unique_ptr<Date> u1(new Date(1, 1, 1));
//	hbx::unique_ptr<Date> u2(move(u1));
//	return 0;
//}

//struct ListNode
//{
//	int _data;
//	std::shared_ptr<ListNode> _next;
//	std::shared_ptr<ListNode> _prev;
//	// 这里改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
//	// 不增加n2的引用计数，不参与资源释放的管理，就不会形成循环引用了
//	/*std::weak_ptr<ListNode> _next;
//	std::weak_ptr<ListNode> _prev;*/
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};
//
//int main()
//{
//	// 循环引用 -- 内存泄露
//	std::shared_ptr<ListNode> n1(new ListNode);
//	std::shared_ptr<ListNode> n2(new ListNode);
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//	n1->_next = n2;
//	n2->_prev = n1;
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//	// weak_ptr不支持管理资源，不支持RAII
//	// weak_ptr是专⻔绑定shared_ptr，不增加他的引用计数，作为⼀些场景的辅助管理
//	//std::weak_ptr<ListNode> wp(new ListNode);
//	return 0;
//}

int main()
{
	std::shared_ptr<string> sp1(new string("111111"));
	std::shared_ptr<string> sp2(sp1);
	std::weak_ptr<string> wp = sp1;
	/*cout << wp.expired() << endl;
	cout << wp.use_count() << endl;*/

	// sp1和sp2都指向了其他资源，则weak_ptr就过期了
	sp1 = make_shared<string>("222222");
	cout << wp.expired() << endl;
	cout << wp.use_count() << endl;
	sp2 = make_shared<string>("333333");
	cout << wp.expired() << endl;
	cout << wp.use_count() << endl;

	wp = sp1;
	//std::shared_ptr<string> sp3 = wp.lock();
	auto sp3 = wp.lock();
	cout << wp.expired() << endl;
	cout << wp.use_count() << endl;
	return 0;
}